'use strict';

const request = require('request-json');
// const normalizer = require('json-api-normalizer').default;
const Jsona = require('jsona').default;
const isPlainObject = require('lodash/isPlainObject');
const isArray = require('lodash/isArray');
const isInteger = require('lodash/isInteger');
// const isString = require('lodash/isString');
const dataFormatter = new Jsona();

module.exports = class requestJsonApi {
  constructor ({ host, url, dataType }) {
    // 初始化请求地址
    this.client = request.createClient(host, { gzip: true });
    this.url = url;
    this.dataType = dataType;
  }

  /**
  * get接口
  * @author wangbinxiang
  * @date   2016-09-23T12:16:10+0800
  * @param  quert {
  *   idList 数字数组或者数字id 格式1: 1,2,3; 格式2: 123;
  *   filters,
  *   pages,
  *   sort,
  *   includes,
  *   fields
  * }
  * @return object or throw error
  *
  */
  async get (query, { successCode = 200 } = {}) {
    const url = jsonApiGetUrl(this.url, query);
    console.log(url);
    const { res, body } = await this.client.get(url);
    if (res.statusCode === successCode) {
      return dataFormatter.deserialize(body);
    } else {
      return null;
      // throw new Error('jsonapi response status is not ' + successCode + '; get ' + res.statusCode);
    }
  }

  async post (attributes, { successCode = 201, path = '' } = {}) {
    const url = this.url + path;
    console.log(url);

    const data = {
      data: {
        type: this.dataType,
        attributes
      }
    };
    const { res, body } = await this.client.post(url, data);
    if (res.statusCode === successCode) {
      return dataFormatter.deserialize(body);
    } else {
      console.log('jsonapi response status is not ' + successCode + '; get ' + res.statusCode);
      return null;
      // throw new Error('jsonapi response status is not ' + successCode + '; get ' + res.statusCode);
    }
  }

  async put (attributes, { successCode = 200, path = '' } = {}) {
    const url = this.url + path;
    console.log(url);

    const data = {
      data: {
        type: this.dataType,
        attributes
      }
    };

    const { res, body } = await this.client.put(url, data);
    if (res.statusCode === successCode) {
      return dataFormatter.deserialize(body);
    } else {
      return null;
      // throw new Error('jsonapi response status is not ' + successCode + '; get ' + res.statusCode);
    }
  }

  async del (path) {

  }
};

function jsonApiGetUrl (baseUrl, query) {
  let url = baseUrl;
  if (query) {
    const {
      idList,
      filters,
      pages,
      sort,
      includes,
      fields } = query;
    if (idList) {
      const idsUrl = buildJsonApiIdsUrl(idList);
      url += '/' + idsUrl;
    }
    if (filters || pages || sort || includes || fields) {
      const queryUrl = buildJsonApiQueryUrl(filters, pages, sort, includes, fields);
      url += queryUrl;
    }
  }
  return url;
}

/**
 * idList转换成ids； idlist 格式1: [1,2,3]; 格式2: 123; ids结果 格式1: 1,2,3; 格式2: 123;
 * @author wangbinxiang
 * @date   2016-09-23T12:16:10+0800
 * @param  {array or int}                 idList 数字数组或者数字id
 * @return {err, string}                       err  null or Error('error params idList')
 *                                        ids  格式1: 1,2,3; 格式2: 123;
 */
function buildJsonApiIdsUrl (idList) {
  let idString;
  if (isArray(idList)) {
    idString = idList.join();
  } else if (isInteger(parseInt(idList))) {
    idString = idList.toString();
  }
  return idString;
}

/**
   * 将搜索条件转为 Json api url 搜索参数
   * @author wangbinxiang
   * @date   2016-09-23T17:18:43+0800
   * @param  { object }                 filters [description]
   * @return {[string]}                         json api url 搜索参数
   */
function buildJsonApiQueryUrl (filters, pages, sort, includes, fields) {
  let url = '';
  let urlList = [];
  if (isPlainObject(filters) && Object.keys(filters).length > 0) {
    for (let i in filters) {
      urlList.push('filter[' + i + ']=' + filters[i]);
    }
  }
  if (isPlainObject(pages) && Object.keys(pages).length > 0) {
    for (let i in pages) {
      urlList.push('page[' + i + ']=' + pages[i]);
    }
  }

  if (isPlainObject(fields) && Object.keys(fields).length > 0) {
    for (let i in fields) {
      urlList.push('fields[' + i + ']=' + fields[i]);
    }
  }

  if (sort) {
    urlList.push('sort=' + sort);
  }

  if (includes && isArray(includes)) {
    urlList.push('include=' + includes.join(','));
  }

  if (urlList.length > 0) {
    url = '?' + urlList.join('&');
  }

  return url;
}
